﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Windows.Markup;
using ICSharpCode.TextEditor.Document;
using Microsoft.Samples.KMoore.WPFSamples.VisualTreeViewer;
using System.Diagnostics;

namespace XamlTune
{
    /// <summary>
    /// Interaction logic for Output.xaml
    /// </summary>
    public partial class Output : Window
    {
        public Output()
        {
            InitializeComponent();
            InputWindow = new Input();
            InputWindow.Loaded += new RoutedEventHandler(InputWindow_Loaded);
            InputWindow.WindowStyle = WindowStyle.ToolWindow;
            InputWindow.XamlContentChanged += new EventHandler(InputWindow_XamlContentChanged);


            textControl.Document.DocumentChanged += new DocumentEventHandler(Document_DocumentChanged);
            scaleTransform = new ScaleTransform();
        }

        void InputWindow_Loaded(object sender, RoutedEventArgs e)
        {
            if (!string.IsNullOrEmpty(InputWindow.XamlContent))
            {
                convertXml(true);
            }
        }

        public Input InputWindow { get; private set; }


        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            InputWindow.Show();
            textControl.Document.HighlightingStrategy = HighlightingStrategyFactory.CreateHighlightingStrategy("XML");
            textControl.Document.FormattingStrategy = new DefaultFormattingStrategy();
            //textControl.Document.FoldingManager = new FoldingManager(textControl.Document, new CustomLineManager(
            if (App.Arguments != null)
            {
                if (App.Arguments.Length >= 1)
                {
                    try
                    {
                        tboutput.Text = System.IO.Path.ChangeExtension(App.Arguments[0], ".xaml");
                    }
                    catch
                    {
                    }
                }

                if (App.Arguments.Length >= 2)
                {
                    tboutput.Text = App.Arguments[1];
                }
            }
        }

        void InputWindow_XamlContentChanged(object sender, EventArgs e)
        {
            //convertXml();
        }

        private void btnLaunch_Click(object sender, RoutedEventArgs e)
        {
            convertXml(false);
        }


        private Canvas cvContent;
        void Document_DocumentChanged(object sender, DocumentEventArgs e)
        {
            StringBuilder sbdoc = new StringBuilder(textControl.Text);
            sbdoc.Replace(XamlTuner.slNamespace, XamlTuner.wpfNamespace);
            treeView.ItemsSource = null;

            try
            {
                System.IO.MemoryStream ms = new System.IO.MemoryStream(Encoding.Default.GetBytes(sbdoc.ToString()));
                if (cvContent != null)
                    cvContent.Loaded -= cv_Loaded;
                cvContent = new Canvas();
                cvContent.Loaded += cv_Loaded;
                cvContent.Children.Add((UIElement)XamlReader.Load(ms));
                scrollViewer1.Content = cvContent;
                cvContent.LayoutTransform = scaleTransform;


                //VisualTreeItem _vti = new VisualTreeItem((DependencyObject) scrollViewer1.Content);
                LogicalTreeItem lfi = new LogicalTreeItem((DependencyObject)scrollViewer1);
                treeView.ItemsSource = lfi.Children;
            }
            catch
            {
            }
        }

        void cv_Loaded(object sender, RoutedEventArgs e)
        {
            Canvas cv = (Canvas)sender;
            refreshCvContent(cv);
        }

        private static void refreshCvContent(Canvas cv)
        {
            if (cv == null)
                return;

            Rect bnds = VisualTreeHelper.GetDescendantBounds(cv);
            if (bnds.IsEmpty)
                return;
            cv.Width = bnds.BottomRight.X;
            cv.Height = bnds.BottomRight.Y;
        }




        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (System.IO.File.Exists(tboutput.Text))
            {
                if (MessageBox.Show("Do you want to owerwrite " + tboutput.Text + "?", "File already exists", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
                {
                    return;
                }
            }
            try
            {
                System.IO.File.WriteAllText(tboutput.Text, textControl.Text);
            }
            catch
            {
            }
        }

        private void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            LogicalTreeItem treeItem = e.NewValue as LogicalTreeItem;
            if (treeItem == null)
                infos.Text = string.Empty;
            else
            {
                Visual v = treeItem.Element as Visual;
                if (v != null)
                {
                    //selectXaml(v);
                    Rect rect = VisualTreeHelper.GetContentBounds(v);
                    Rect rect2 = VisualTreeHelper.GetDescendantBounds(v);
                    infos.Text = "Bounding box: " + rect.ToString()
                        + Environment.NewLine
                        + "Descendant BBox: " + rect2;
                }
                else
                {
                    infos.Text = "Node is not a Visual";
                }
            }
        }

        ScaleTransform scaleTransform;

        private void sliderZoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {

            if (scaleTransform == null)
            {
                scaleTransform = new ScaleTransform();
            }
            scaleTransform.ScaleX = e.NewValue;
            scaleTransform.ScaleY = e.NewValue;
            refreshCvContent(cvContent);
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            InputWindow.Close();
        }

        private void convertXml(bool forceReadInput)
        {
            string input;
            if (forceReadInput || rbTransformInput.IsChecked == true)
            {
                InputWindow.Convert();
                input = InputWindow.XamlContent;
            }
            else
                input = textControl.Text;

            textControl.Text = XamlTuner.Tune(rbSilverlight.IsChecked.GetValueOrDefault()
                , cbReplaceRectangleGeometry.IsChecked.GetValueOrDefault()
                , cbCanvasBoundingBox.IsChecked.GetValueOrDefault()
                , cbRemoveNull.IsChecked.GetValueOrDefault()
                , cbRemoveDefaultValues.IsChecked.GetValueOrDefault()
                , cbExcludeCollapsedFromBoundingBox.IsChecked.GetValueOrDefault()
                , input);

        }

        //private void selectXaml(Visual v)
        //{
        //    FrameworkElement elem = v as FrameworkElement;
        //    if (elem != null)
        //    {
        //        //XmlDocument doc2 = new XmlDocument();
        //        //XmlNamespaceManager mgr = new XmlNamespaceManager(new NameTable());
        //        //mgr.AddNamespace("wpf", wpfNamespace);
        //        //mgr.AddNamespace("x", "http://schemas.microsoft.com/winfx/2006/xaml");
        //        //mgr.AddNamespace("sl", slNamespace);
        //        System.IO.MemoryStream ms = new System.IO.MemoryStream(Encoding.Default.GetBytes(textControl.Text));

        //        //LogicalTreeHelper
        //        long lastPos = 0;

        //        XmlReader r = new XmlTextReader(ms);
        //        while (r.Read())
        //        {
        //            long position = ms.Position;
        //            string name = r.GetAttribute("Name", xNamespace);
        //            if(StringComparer.Ordinal.Compare(name, 
        //            //r.
        //            //sr.
        //            //r.
        //            lastPos = position;
        //        }
        //    }
        //}

    }
}